package org.codehaus.mojo.wagon;

import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugins.annotations.Parameter;
import org.apache.maven.wagon.ConnectionException;
import org.apache.maven.wagon.Wagon;
import org.apache.maven.wagon.WagonException;

import java.io.IOException;

/**
 * Provides base functionality for dealing with I/O using single wagon.
 */
public abstract class AbstractSingleWagonMojo extends AbstractWagonMojo {

    /**
     * URL to upload to  from or list. Must exist and point to a directory.
     */
    @Parameter(property = "wagon.urls", required = true)
    protected String[] urls;

    /**
     * settings.xml's server id for the URL. This is used when wagon needs extra authentication information.
     */
    @Parameter(property = "wagon.serverId", defaultValue = "serverId")
    private String serverId;

    @Override
    public void execute() throws MojoExecutionException {
        if (this.skip) {
            this.getLog().info("Skip execution.");
            return;
        }
        for (String url : urls) {
            executeItem(url);
        }
    }

    public void execute(String url) throws MojoExecutionException {
        if (this.skip) {
            this.getLog().info("Skip execution.");
            return;
        }
        executeItem(url);
    }

    private void executeItem(String url) throws MojoExecutionException {
        Wagon wagon = null;
        try {
            wagon = createWagon(serverId, url);
            execute(wagon);
        } catch (WagonException | IOException e) {
            throw new MojoExecutionException("Error handling resource", e);
        } finally {
            try {
                if (wagon != null) {
                    wagon.disconnect();
                }
            } catch (ConnectionException e) {
                getLog().debug("Error disconnecting wagon - ignored", e);
            }
        }
    }

    /**
     * Perform the necessary action. To be implemented in the child mojo.
     *
     * @param wagon - wagon instance to use
     * @throws MojoExecutionException if any execution error
     * @throws WagonException         if any wagon error
     * @throws IOException            if any io error
     */
    protected abstract void execute(Wagon wagon) throws MojoExecutionException, WagonException, IOException;

}